<?php

class Request
{
    const GET  = 'get';
    const POST = 'post';

    const STANDARD_HTTP_PORT = 80;
    const STANDARD_HTTP_PROTOCOL = 'http';

    const STANDARD_HTTPS_PORT = 443;
    const STANDARD_HTTPS_PROTOCOL = 'https';

    protected static $uri;
    protected static $ipAddress;
    protected static $method;

    protected static $getParams = null;
    protected static $postParams = null;
    protected static $allParams = null;

    private function __construct()
    {
    }

    public static function GetParams( $method = null )
    {
        if ( is_null(self::$getParams) )
        {
            self::$getParams = $_GET;
        }

        if ( is_null(self::$postParams) )
        {
            self::$postParams = $_POST;
        }

        if ( is_null(self::$allParams) )
        {
            self::$allParams = $_REQUEST;
        }

        if ( $method == Request::GET )
        {
            if ( isset(self::$getParams['path']) )
            {
                unset(self::$getParams['path']);
            }
            return self::$getParams;
        }

        if ( $method == Request::POST )
        {
            return self::$postParams;
        }

        if ( isset(self::$allParams['path']) )
        {
            unset(self::$allParams['path']);
        }
        return self::$allParams;
    }

    public static function GetParam( $name, $defValue = '', $method = null )
    {
        $arr = self::GetParams( $method );

        $value = isset($arr[$name]) ? $arr[$name] : $defValue;
        if ( !is_null($value) && is_string( $value ) && get_magic_quotes_gpc() )
        {
            $value = stripslashes($value);
        }
        return $value;
    }

    public static function Get( $name, $defValue = '' )
    {
        return self::GetParam($name, $defValue, self::GET);
    }

    public static function Post( $name, $defValue = '' )
    {
        return self::GetParam($name, $defValue, self::POST);
    }

    public static function SetParam( $name, $value, $method = null )
    {
        $params = self::GetParams( $method );

        if ($method == Request::GET || empty($method))
        {
            self::$getParams[$name] = $value;
        }
        else if ($method == Request::POST || empty($method))
        {
            self::$postParams[$name] = $value;
        }

        self::$allParams[$name] = $value;
    }

    public static function GetMethod()
    {
        if (!self::$method)
        {
            self::$method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : self::GET;
        }
        return self::$method;
    }

    public static function IsMethod($method)
    {
        return strtoupper($method) == self::GetMethod();
    }

    /**
     * Returns whether this is an AJAX (XMLHttpRequest) request.
     * @return boolean whether this is an AJAX (XMLHttpRequest) request.
     */
    public static function IsAjaxRequest()
    {
        return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';
    }

    public static function GetURL()
    {
        $url = '';
        // for nginx as proxy for Apache
        if (isset($_SERVER['HTTP_X_REAL_URL']))
        {
            $url = $_SERVER['HTTP_X_REAL_URL'];
        }
        // for IIS with rewrite module (IIFR, ISAPI Rewrite, ...)
        else if (isset($_SERVER['HTTP_X_REWRITE_URL']))
        {
            $url = $_SERVER['HTTP_X_REWRITE_URL'];
        }
        else
        {
            $url = $_SERVER['REQUEST_URI'] ? $_SERVER['REQUEST_URI'] : '';
        }

        return $url;
    }

    public static function GetUri()
    {
        if (!isset(self::$uri))
        {
            $url = self::GetURL();

            self::$uri = self::getUriPrefix() . $url;
        }


        return self::$uri;
    }

    public static function GetUriPrefix()
    {
        if (self::IsSecure())
        {
            $standardPort = self::STANDARD_HTTPS_PORT;
            $protocol = self::STANDARD_HTTPS_PROTOCOL;
        }
        else
        {
            $standardPort = self::STANDARD_HTTP_PORT;
            $protocol = self::STANDARD_HTTP_PROTOCOL;
        }

        $host = explode(":", self::getHost());
        if (count($host) == 1)
        {
            $host[] = self::GetPort();
        }

        if ($host[1] == $standardPort || empty($host[1]))
        {
            unset($host[1]);
        }

        return $protocol.'://'.implode(':', $host);
    }

    public static function GetPort()
    {
        return isset($_SERVER['HTTP_X_SERVER_PORT'])
            ? $_SERVER['HTTP_X_SERVER_PORT']
            : (isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : '');
    }

    public static function GetHost()
    {
        return isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '');
    }

    public static function GetRemoteAddress()
    {
        if ( !isset(self::$ipAddress) )
        {
            self::$ipAddress = null;

            if ( isset($_SERVER["HTTP_X_FORWARDED_FOR"]) )
            {
                // This header is a comma-separated list of IP addresses
                $ipList = explode(',', $_SERVER["HTTP_X_FORWARDED_FOR"]);
                if (count($ipList) > 0)
                {
                    self::$ipAddress = trim($ipList[0]);
                }
            }
            else if ( isset($_SERVER["REMOTE_ADDR"]) )
            {
                self::$ipAddress = $_SERVER['REMOTE_ADDR'];
            }
        }

        return self::$ipAddress;
    }

    public static function GetRemoteHost()
    {
        $ipAddress = self::GetRemoteAddress();
        return $ipAddress ? @getHostByAddr($ipAddress) : '';
    }

    public static function IsSecure()
    {
        return ( (isset($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) == 'on' || $_SERVER['HTTPS'] == 1))
            || (isset($_SERVER['HTTP_SSL_HTTPS']) && (strtolower($_SERVER['HTTP_SSL_HTTPS']) == 'on' || $_SERVER['HTTP_SSL_HTTPS'] == 1))
            || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') );
    }

    public static function GetReferer()
    {
        return isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
    }

    public static function GetUserAgent()
    {
        return isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
    }

    /**
     * Detects user operation system by user agent.
     * Returns empty string if detection was failed.
     * @return string
     */
    public static function GetUserOperatingSystem()
    {
        $OSList = array
        (
            // Match user agent string with operating systems
            'Windows 3.11' => 'Win16',
            'Windows 95' => 'Windows 95|Win95|Windows_95',
            'Windows 98' => 'Windows 98|Win98',
            'Windows 2000' => 'Windows NT 5\.0|Windows 2000',
            'Windows XP' => 'Windows NT 5\.1|Windows XP',
            'Windows 2003' => 'Windows NT 5\.2',
            'Windows Vista' => 'Windows NT 6\.0',
            'Windows 7' => 'Windows NT 6\.1',
            'Windows NT 4.0' => 'Windows NT 4\.0|WinNT4\.0|WinNT|Windows NT',
            'Windows ME' => 'Windows ME',
            'Open BSD' => 'OpenBSD',
            'Sun OS' => 'SunOS',
            'Linux' => 'Linux|X11',
            'Mac OS' => 'Mac_PowerPC|Macintosh',
            'QNX' => 'QNX',
            'BeOS' => 'BeOS',
            'OS/2' => 'OS\/2',
            'Search Bot'=>'nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver',
            'iOS' => 'iPod|iPad|iPhone'
        );

        $userOS = "";

        $userAgent = self::GetUserAgent();
        if ( !empty($userAgent) )
        {
            foreach ($OSList as $currOS => $matchPattern)
            {
                if ( preg_match("/" . $matchPattern . "/i", $userAgent) )
                {
                    $userOS = $currOS;
                    break;
                }
            }
        }

        return $userOS;
    }

    public static function IsClientPlatformWin64()
    {
        return ((stripos(self::GetUserAgent(), 'wow64') !== false ) || (stripos(self::GetUserAgent(), 'win64') !== false ));
    }

    public static function GetCookie($name, $defaultValue = null)
    {
        $cookie = $defaultValue;

        if (isset($_COOKIE[$name]))
        {
            $cookie = get_magic_quotes_gpc() ? Util::StripSlashesDeep($_COOKIE[$name]) : $_COOKIE[$name];
        }

        return $cookie;
    }

    public static function HasParam($name, $method = '')
    {
        $arr = self::GetParams($method);

        return isset($arr[$name]);
    }

    /**
     * Redirects to specified URL.
     *
     * @param string $url URL to redirect to
     * @param int $statusCode HTTP status code for redirection.
     *      302 Found by default
     */
    public static function Redirect($url, $statusCode = null)
    {
        if (isset($statusCode))
        {
            header("Location: $url", true, $statusCode);
        }
        else
        {
            header("Location: $url");
        }
        exit();
    }

    /**
     * Redirects to the same page with HTTPS schema if connection is not secure.
     */
    public static function RedirectToHTTPS()
    {
        if ( !self::IsSecure() )
        {
            $url = "https://" . self::GetHost() . self::GetURL();
            self::Redirect( $url );
        }
    }

    /**
     * Redirects to the same page with HTTP
     */
    public static function RedirectToHTTP()
    {
        if ( self::IsSecure() )
        {
            $url = "http://" . self::GetHost() . self::GetURL();
            self::Redirect( $url );
        }
    }

    /**
     * Returns file data
     * @return array
     */
    public static function GetFile($key = 'Filedata')
    {
        return $_FILES[$key];
    }

    public static function HasFile($key = 'Filedata')
    {
        return isset($_FILES[$key]);
    }
}

?>